home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / sys / amiga / amiwbnch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-03  |  12.1 KB  |  519 lines

  1. /*    SCCS Id: @(#)amiwbench.c      3.1   93/01/08
  2. /*    Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990, 1992, 1993 */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*  Amiga Workbench interface  */
  6.  
  7. #include "hack.h"
  8.  
  9. /* Have to #undef CLOSE, because it's used in display.h and intuition.h */
  10. #undef CLOSE
  11.  
  12. #ifdef __SASC
  13. # undef COUNT
  14. # include <proto/exec.h>
  15. # include <proto/dos.h>
  16. # include <proto/icon.h>
  17. #endif
  18.  
  19. #include <workbench/startup.h>
  20. #include <workbench/workbench.h>
  21. #include <exec/memory.h>
  22. #include <ctype.h>
  23.  
  24. #ifdef __SASC
  25. # include <string.h>
  26. # undef strlen          /* grrr */
  27. #endif
  28.  
  29. #define ALLOC_SIZE      ((long)sizeof(struct FileInfoBlock))
  30.  
  31. #ifdef AZTEC_C
  32. # include <functions.h>
  33. extern struct Library *IconBase;
  34. #endif
  35.  
  36. extern void NDECL( preserve_icon );
  37. extern void NDECL( clear_icon );
  38. #ifndef    SHAREDLIB
  39. extern void FDECL( amii_set_text_font, ( char *, int ) );
  40. #endif
  41. extern int FDECL(parse_config_line, (FILE *, char *, char *, char *));
  42. extern char *FDECL( ami_default_icon, ( char * ) );
  43.  
  44. int ami_argc;           /* global argc */
  45. char **ami_argv;        /* global argv */
  46. boolean FromWBench=0;       /* how did we get started? */
  47. boolean FromCLI=0;      /* via frontend and INTERNALCLI */
  48. static BOOL FromTool=0;     /* or from Project (ergo nothing to restore) */
  49. static char argline[80];    /* fake command line from ToolTypes */
  50. static BOOL TTparse=0;      /* parsing tooltypes? */
  51. static BOOL KillIcon=FALSE; /* delayed expunge of user's icon */
  52. static char iconname[PATHLEN+5];
  53. static char origicon[PATHLEN+5];
  54. static char savefname[PL_NSIZ];     /* name from name of save file */
  55. int amibbs=0;            /* BBS mode */
  56.  
  57. #ifdef AMII_GRAPHICS
  58. extern int bigscreen;
  59. #endif
  60. extern const char *classes; /* liberated from pcmain */
  61. extern char PATH[];
  62.  
  63. static void score(char *);
  64.  
  65. /* Called after NetHack.cnf (and maybe NETHACKOPTIONS) are read.
  66.  * If this is a request to show the score file, do it here and quit.
  67.  */
  68. void ami_wbench_init()
  69. {
  70.     struct WBStartup *wbs=(struct WBStartup *)ami_argv;
  71.     struct WBArg *wa;
  72.     int ia;         /* arg of active icon */
  73.     int x,doscore=0;
  74.     char    *p,*lp;
  75.     BPTR    olddir;         /* starting directory */
  76.     struct DiskObject *dobj;
  77.     char    *scorearg, *t;
  78.     char    tmp_levels[PATHLEN];
  79.  
  80.     FromWBench=(ami_argc==0);
  81.     if(!FromWBench)return;          /* nothing if from CLI */
  82.  
  83.     /*
  84.      * "NULL" out arrays
  85.      */
  86.     tmp_levels[0]  = '\0';
  87.  
  88.     IconBase=OpenLibrary("icon.library",33L);
  89.     if(!IconBase)error("icon.library missing!");
  90.  
  91.     wa=wbs->sm_ArgList;
  92.     if(wbs->sm_NumArgs>2)error("You can only play one game at a time!");
  93.     ia=wbs->sm_NumArgs-1;
  94.  
  95.     if(strcmp("NewGame",wa[ia].wa_Name)){
  96.     strcpy(savefname,wa[ia].wa_Name);
  97.     strcpy(plname,wa[ia].wa_Name);
  98.     }
  99.  
  100.     if( ( t = strrchr( plname, '.' ) ) && strcmp( t, ".sav" ) == 0 )
  101.     *t = 0;
  102.  
  103.     olddir=CurrentDir(wa[ia].wa_Lock);   /* where the icon is */
  104.  
  105.     dobj=GetDiskObject(wa[ia].wa_Name);
  106.     (void)CurrentDir(olddir);       /* and back */
  107.     if(!dobj){
  108.     error("Sorry, I can't find your icon!");
  109.     }
  110.  
  111.     FromTool=(dobj->do_Type==WBTOOL)?1:
  112.     (dobj->do_Type==WBPROJECT)?0:
  113.     (error("Sorry, I don't recognize this icon type!"),1);
  114.  
  115.     if(index(savefname,'.') && !strncmp(index(savefname,'.'),".sav",4)){
  116.     *index(savefname,'.')='\0';
  117.     } else {
  118.     savefname[0]='\0';  /* don't override if not save file */
  119.     FromTool = 1;
  120.     }
  121.  
  122.     argline[0]='\0';
  123. #ifdef AMII_GRAPHICS
  124.     if( p = FindToolType( dobj->do_ToolTypes, "SCREEN" ) )
  125.     {
  126.     extern int bigscreen;
  127.     if( MatchToolValue( p, "NOLACE" ) )
  128.         bigscreen = -1;
  129.     else if( MatchToolValue( p, "LACE" ) )
  130.         bigscreen = 1;
  131.     }
  132. #endif
  133.     if(dobj->do_ToolTypes)for(x=0;p=dobj->do_ToolTypes[x];x++){
  134.     lp=index(p,'=');
  135.     if( !lp || strncmp(p, "SCORE", 5 ) == 0 ){
  136.         if((strncmp(p,"SCORES",6)==0) || (strncmp(p,"SCORE",5)==0)){
  137.         if( !lp )
  138.             lp = "";
  139.         else
  140.             ++lp;
  141.         doscore=1;
  142.         scorearg=(char *)alloc(strlen(lp)+1);
  143.         strcpy(scorearg,lp);
  144.         } else {
  145.         TTparse=TRUE;
  146.         parseoptions(p,(boolean)TRUE,(boolean)FALSE);
  147.         TTparse=FALSE;
  148.         }
  149.     } else {
  150.         lp++;
  151.         TTparse=TRUE;
  152.         /* new things */
  153.         if((strncmp(p,"CMDLINE",7)==0)||
  154.           (strncmp(p,"COMMANDLINE",11)==0)||
  155.           (strncmp(p,"INTERNALCLI",11)==0)){
  156.             strncpy(argline,lp,79);
  157.         if(*p=='I'){
  158.             FromTool=0; /* ugly hack bugfix */
  159.             FromCLI=1;  /* frontend ICLI only */
  160.             if(*argline==':'){
  161.             char *x=lp;
  162.             amibbs=1;
  163. #ifdef for_later
  164.             copy to next blank in argline to amibasename
  165.             delete from argline
  166. #else
  167.             while(*x && !isspace(*x))x++;
  168.             while(*x && isspace(*x))x++;
  169.             strncpy(argline,x,79);
  170. #endif
  171.             }
  172.         }
  173.         }
  174.         else if( strncmp( p, "FONT", 4 ) == 0 )
  175.         {
  176.         if( p = strdup( lp ) )
  177.         {
  178.             lp = strchr( p, ':' );
  179.             *lp++ = 0;
  180.             amii_set_text_font( p, atoi( lp ) );
  181.             free( p );
  182.         }
  183.         }
  184.         else if( strncmp( p, "SCREEN",6 ) )
  185.         {
  186.         if (!parse_config_line((FILE *)0, p, 0, tmp_levels)){
  187.             raw_printf("Bad ToolTypes line: '%s'\n",p);
  188.             getreturn("to continue");
  189.         }
  190.         } 
  191.         TTparse=FALSE;
  192.     }
  193.     }
  194.  
  195.     /* cleanup - from files.c, except we only change things
  196.      * that are explicitly changed, since we already
  197.      * did this once to get the defaults (in amidos.c)
  198.      */
  199.  
  200.     if(plname[0]){
  201.     plnamesuffix(); /* from files.c */
  202.     set_savefile_name();
  203.     }
  204.     if(tmp_levels[0])strcpy(permbones,tmp_levels);
  205.     if(tmp_levels[0]){
  206.     strcpy(levels,tmp_levels);
  207.     strcpy(bones,levels);
  208.     }
  209.     FreeDiskObject(dobj);   /* we'll get it again later if we need it */
  210.  
  211.     if(doscore)score(scorearg);
  212.  
  213.         /* if the user started us from the tool icon,
  214.          * we can't save the game in the same place
  215.          * we started from, so pick up the plname
  216.          * and hope for the best.
  217.          */
  218.     if(FromTool){
  219.     set_savefile_name();
  220.     }
  221. }
  222.  
  223. /* Simulate the command line. Note that we do not handle the
  224.  * entire range of standard NetHack flags.
  225.  */
  226. void ami_wbench_args(){
  227.     char *p=argline;
  228.  
  229.     if(!FromWBench) return;
  230.  
  231.     while(*p){
  232.     switch(*p++){
  233.     case ' ':
  234.     case '-':   break;
  235. #ifdef NEWS
  236.     case 'n':   flags.news = FALSE;
  237. #endif
  238. #if defined(WIZARD) || defined(EXPLORE_MODE)
  239. # ifndef EXPLORE_MODE
  240.     case 'X':
  241. # endif
  242.     case 'D':
  243. # ifdef WIZARD
  244. #  ifdef KR1ED
  245.         if(!strcmp(plname,WIZARD_NAME))
  246. #  else
  247.         if(!strcmp(plname,WIZARD))
  248. #  endif
  249.         {
  250.         wizard=TRUE;break;
  251.         }
  252.         /* else fall through */
  253. # endif
  254. # ifdef EXPLORE_MODE
  255.     case 'X':   discover=TRUE;
  256. # endif
  257.         break;
  258. #endif
  259. #ifdef AMII_GRAPHICS
  260.     case 'L':   /* interlaced screen */
  261.         bigscreen = 1;
  262.         break;
  263.     case 'l':   /* No interlaced screen */
  264.         bigscreen = -1;
  265.         break;
  266. #endif
  267.     case 'u':
  268.         {
  269.         char *c,*dest;
  270.         while(*p && isascii(*p) && isspace(*p))p++;
  271.         c=p;
  272.         dest=plname;
  273.         for(;*p && isascii(*p) && !isspace(*p);){
  274.         if(dest-plname>=(sizeof(plname)-1))break;
  275.         *dest++=*p++;
  276.         }
  277.         *dest='\0';
  278.         if(c==dest)
  279.         raw_print("Player name expected after -u");
  280.         }
  281.         strcpy(savefname,plname);
  282.         set_savefile_name();
  283.         break;
  284.     case 's':
  285.         score(p);
  286.         /* NOTREACHED */
  287.     default:
  288.         p--;
  289.         if(index(classes,toupper(*p))){
  290.         char *t=pl_character;
  291.         int cnt=sizeof(pl_character)-1;
  292.         while(cnt && *p && !isspace(*p))*t++=*p++,cnt--;
  293.         *t=0;
  294.         break;
  295.         }
  296.         raw_printf("Unknown switch: %s\n",p);
  297.         /* FALL THROUGH */
  298.     case '?':
  299.         {
  300.         char buf[77];
  301.  
  302.         raw_printf("Usage: %s -s [-[%s]] [maxrank] [name]...",
  303.           hname, classes);
  304.         raw_print("       or");
  305.         sprintf(buf,"       %s [-u name] [-[%s]]", hname, classes);
  306. #if defined(WIZARD) || defined(EXPLORE_MODE)
  307.         strcat(buf," [-[DX]]");
  308. #endif
  309. #ifdef NEWS
  310.         strcat(buf," [-n]");
  311. #endif
  312. #ifdef MFLOPPY
  313. # ifndef AMIGA
  314.         strcat(" [-r]");
  315. # endif
  316. #endif
  317.         raw_print(buf);
  318.         exit(0);
  319.         }
  320.     }
  321.     }
  322. }
  323.  
  324.  
  325. /* IF (from workbench) && (currently parsing ToolTypes)
  326.  * THEN print error message and return 0
  327.  * ELSE return 1
  328.  */
  329. ami_wbench_badopt(oopsline)
  330. const char *oopsline;
  331. {
  332.     if(!FromWBench)return 1;
  333.     if(!TTparse)return 1;
  334.  
  335.     raw_printf("Bad Syntax in OPTIONS in ToolTypes: %s.",oopsline);
  336.     return 0;
  337. }
  338.  
  339. /* Construct (if necessary) and fill in icon for given save file */
  340. void ami_wbench_iconwrite(base)
  341. char *base;
  342. {
  343.     BPTR lock;
  344.     char tmp[PATHLEN+5];
  345.     char *n;
  346.  
  347.     if(!FromWBench)return;
  348.     if(FromCLI)return;
  349.  
  350.     strcpy(tmp,base);
  351.     strcat(tmp,".info");
  352.  
  353.     /* Get the name of the icon */
  354.     n = ami_default_icon( DEFAULT_ICON );
  355.     if(FromTool){               /* user clicked on main icon */
  356.     (void)CopyFile( n, tmp );
  357.     } else {                /* from project */
  358.     lock=Lock(tmp,ACCESS_READ);
  359.     if(lock==0){    /* maybe our name changed - try to get
  360.              * original icon */
  361.         if(!Rename(origicon,tmp)){
  362.         /* nope, build a new icon */
  363.         lock=Lock( n, ACCESS_READ);
  364.         if(lock==0)return;      /* no icon today */
  365.         UnLock(lock);
  366.         (void)CopyFile( n,tmp);
  367.         }
  368.     } else UnLock(lock);
  369.     }
  370.     KillIcon=FALSE;
  371. }
  372.  
  373. /* How much disk space will we need for the icon? */
  374. int ami_wbench_iconsize(base)
  375. char *base;
  376. {
  377.     struct FileInfoBlock *fib;
  378.     BPTR lock;
  379.     int rv;
  380.     char tmp[PATHLEN+5];
  381.  
  382.     if(!FromWBench)return(0);
  383.     if(FromCLI)return(0);
  384.  
  385.     strcpy(tmp,base);
  386.     strcat(tmp,".info");
  387.     lock=Lock(tmp,ACCESS_READ);
  388.     if(lock==0){    /* check the default */
  389.     lock=Lock( ami_default_icon( DEFAULT_ICON ),ACCESS_READ);
  390.     if(lock==0)return(0);
  391.     }
  392.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  393.     if(!Examine(lock,fib)){
  394.     UnLock(lock);
  395.     FreeMem(fib, ALLOC_SIZE);
  396.     return(0);          /* if no icon, there never will be one */
  397.     }
  398.     rv=fib->fib_Size+strlen(plname);    /* guessing */
  399.     UnLock(lock);
  400.     FreeMem(fib, ALLOC_SIZE);
  401.     return(rv);
  402. }
  403.  
  404. char *
  405. ami_default_icon( defname )
  406.     char *defname;
  407. {
  408.     static char name[ 300 ];
  409.  
  410.     strcpy( name, "NetHack:x.icon" );
  411.     name[ 8 ] = pl_character[ 0 ];
  412.  
  413.     if( access( name, 0 ) == 0 )
  414.         return( name );
  415.  
  416.     return( defname );
  417. }
  418.  
  419. /* Delete the icon associated with the given file (NOT the file itself! */
  420. /* (Don't worry if the icon doesn't exist */
  421. void ami_wbench_unlink(base)
  422. char *base;
  423. {
  424.     if(!FromWBench)return;
  425.     if(FromCLI)return;
  426.  
  427.     strcpy(iconname,base);
  428.     strcat(iconname,".info");
  429.     KillIcon=TRUE;          /* don't do it now - this way the user
  430.                  * gets back whatever picture we had
  431.                  * when we started if the game is
  432.                  * saved again           */
  433. }
  434.  
  435. static int preserved=0;        /* wizard mode && saved save file */
  436.  
  437. void
  438. preserve_icon(){
  439.     preserved=1;
  440. }
  441.  
  442. void
  443. clear_icon(){
  444.     if(!FromWBench)return;
  445.     if(FromCLI)return;
  446.     if(preserved)return;
  447.     if(!KillIcon)return;
  448.  
  449.     DeleteFile(iconname);
  450. }
  451.  
  452. /* Check for a saved game.
  453. IF not a saved game -> -1
  454. IF can't open SAVEF -> -1
  455. ELSE -> fd for reading SAVEF */
  456. int ami_wbench_getsave(mode)
  457. int mode;
  458. {
  459.     BPTR lock;
  460.     struct FileInfoBlock *fib;
  461.  
  462.     if(!FromWBench)return(open(SAVEF,mode));
  463.         /* if the file will be created anyway, skip the
  464.          * checks and just do it            */
  465.     if(mode & O_CREAT)return(open(SAVEF,mode));
  466.     if(FromTool)return(-1);    /* otherwise, by definition, there
  467.                  * isn't a save file (even if a
  468.                  * file of the right name exists) */
  469.     if(savefname[0])
  470.     strncpy(plname,savefname,PL_NSIZ-1); /* restore poly'd name */
  471.     lock=Lock(SAVEF,ACCESS_READ);
  472.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  473.     if(lock && Examine(lock,fib)){
  474.     if(fib->fib_Size>100){  /* random number << save file size */
  475.         UnLock(lock);
  476.         FreeMem(fib,ALLOC_SIZE);
  477.         return(open(SAVEF,mode));
  478.     } else {
  479.         /* this is a dummy file we need because
  480.          * workbench won't duplicate an icon with no
  481.          * "real" data attached - try to get rid of it.
  482.          */
  483.         UnLock(lock);
  484.         unlink(SAVEF);
  485.         FreeMem(fib,ALLOC_SIZE);
  486.         return(-1);
  487.     }
  488.     }
  489.     FreeMem(fib,ALLOC_SIZE);
  490.     return(-1);     /* give up */
  491. }
  492.  
  493. static void
  494. score(scorearg)
  495.     char *scorearg;
  496.         {
  497.     long ac;
  498.     char *p;
  499.     char **av=calloc(1,50*sizeof(char *));
  500.  
  501. #ifdef CHDIR
  502.     chdirx(hackdir,0);
  503. #endif
  504.     av[0]="NetHack";            /* why not? */
  505.     av[1]="-s";             /* why not? */
  506.     av[2]=0;
  507.     for(ac=2,p=scorearg;*p;ac++){
  508.         av[ac]=p;av[ac+1]=0;
  509.         while(*p && !isspace(*p))p++;
  510.         if(!*p)break;
  511.         *p++='\0';
  512.         while(*p && isspace(*p))p++;
  513.         /* *p='\0';    /* extra? */
  514.     }
  515.     prscore(ac+1,av);
  516.     free( av );
  517.     exit(0);        /* #defined to msexit() */
  518. }
  519.